package org.itboys.product.service;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.itboys.admin.constant.AdminSessionConstant;
import org.itboys.admin.dto.EasyUiTreeDO;
import org.itboys.commons.utils.servlet.ServletContextHolder;
import org.itboys.dto.ProductDTO;
import org.itboys.dto.ProductDetail;
import org.itboys.mongodb.core.MongoDataSource;
import org.itboys.mongodb.service.BaseService;
import org.itboys.oss.OssService;
import org.itboys.product.cache.ProductDetailLoader;
import org.itboys.product.cache.ProductLoader;
import org.itboys.product.constant.ProductConstant;
import org.itboys.product.entity.*;
import org.itboys.product.productenum.ProductCategoryEnum;
import org.itboys.product.search.ProductSearchDoc;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.UpdateOperations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.multipart.MultipartFile;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Service
public class ProductService  extends BaseService<Product, Long>{
	
	private static final long serialVersionUID = 6480335544000649473L;


	@Resource(name = "ossService")
    OssService productOssService;

	@Resource(name = "productDS")
	private MongoDataSource ds;

	@Resource(name = "productLoader")
	private ProductLoader productLoader;

	@Resource(name = "productDetailLoader")
	private ProductDetailLoader productDetailLoader;

	@Resource(name = "productCategoryService")
	private ProductCategoryService productCategoryService;

	@Autowired
	private ProductCategorySpecService productCategorySpecService;
	@Autowired
	private ProductCategorySpecDetailService productCategorySpecDetailService;
	@Autowired
	private ProductSpecService productSpecService;
	@Autowired
	private ProductSpecDetailService productSpecDetailService;

//	@Resource(name = "productSearchService")
//	private ProductSearchService productSearchService;
	
	@Override
	protected MongoDataSource getMongoDataSource() {
		return ds;
	}

	@Override
	protected Class<Product> getEntityClass() {
		return Product.class;
	}
	
	public ProductDetail getProductDetail(long productId) {
		return productDetailLoader.get(productId);
	}

	public List<ProductDetail> getProductDetail(List<Long> productIds) {
		return productDetailLoader.getValues(productIds);
	}

    public List<ProductCategory> getProductCategory(long productId) {
        Product product = getById(productId);
        if (product == null) {
            return Collections.emptyList();
        }
        return productCategoryService.getByIds(product.getCategoryId());
    }

	public List<ProductDTO> getProductDTOList(List<Long> productIds) {
		return productLoader.getValues(productIds);
	}

	public Map<Long , ProductDTO> getProductMap(List<Long> productIds) {
		return productLoader.getValueMap(productIds);
	}

	/**
	 * 新增或修改
	 * @param product
	 * @return
	 */
	public boolean insert(Product product, MultipartFile imgFile, MultipartFile[] imgFiles, List<Long> specDetails, String productSpecDetails){
		try{
            Object shopCenterId = ServletContextHolder.getSession().getAttribute(AdminSessionConstant.SHOP_CENTER_ID);
			//组装商品主图
			String tempFile = null;
    		if(imgFile != null && !imgFile.isEmpty()){
    			tempFile = productOssService.upload(imgFile.getInputStream(), ProductConstant.ImgPath.OSS_PATH);
    			product.setImage(ProductConstant.OSS_URL_PREFIX + ProductConstant.ImgPath.OSS_PATH + "/" + tempFile);
			}
			if(imgFiles != null && imgFiles.length > 0){
				List<String> images = Lists.newArrayListWithExpectedSize(imgFiles.length);
				for (MultipartFile file : imgFiles) {
					if(file != null && !file.isEmpty()){
						String image = productOssService.upload(file.getInputStream(), ProductConstant.ImgPath.OSS_PATH);
						image = ProductConstant.OSS_URL_PREFIX + ProductConstant.ImgPath.OSS_PATH + "/" + image;
						images.add(image);
					}
				}
				product.setImages(images);
			}
            if (shopCenterId != null) {  //店铺后台录入的
                product.setCenterId((Long) shopCenterId);
                product.setProductType(((Long)ServletContextHolder.getSession().getAttribute(AdminSessionConstant.SHOP_TYPE)).intValue());
            } else {
                product.setProductType(ProductCategoryEnum.PRODUCCT.getType());
            }
			if(product.getId() != 0){
				//TODO 删除以前的搜索标签
				//TODO 重设商品搜索标签
                Product old = getById(product.getId());
                if (CollectionUtils.isEmpty(product.getImages()) && CollectionUtils.isNotEmpty(old.getImages())) {
                    product.setImages(old.getImages());
                }
				update(product);
				//清空商品缓存
				clearProductCache(product.getId());
			}else{
				//组装搜索标签
				/*if(tagsArr != null && tagsArr.length > 0){
					searchTagService.appendProductTag(Lists.newArrayList(tagsArr) , product.getId());
				}*/
				save(product);
			}
			//修改规格
			productSpecService.insert(product.getId(), specDetails);
			//修改规格明细
			productSpecDetailService.insert(productSpecDetails, product.getId());
			ProductSearchDoc searchDoc = new ProductSearchDoc();
			searchDoc.setPrice(product.getPrice());
//			searchDoc.setBrandId(product.getBrandId());
			// TODO searchDoc.setCategoryFullIdPath();
			searchDoc.setProductId(product.getId());
			//TODO 将商品名称 标签 品牌名称 分类名称 合成一个字符串 到productName 里
			searchDoc.setProductName(product.getName());
			//异步构建商品搜索引擎
//			productSearchService.buildProductSearchIndex(searchDoc);
			return true;
		}catch(Exception e){
			logger.error("ProductService.save error", e);
		}
		return false;
	}
	
	/**
	 * 修改商品状态
	 * @param productId
	 * @param status
	 * @return
	 */
	public boolean updateState(Long productId, int status){
		try{
			Product product = getById(productId);
			product.setStatus(status);
			update(product);
			return true;
		}catch(Exception e){
			e.printStackTrace();
			logger.error("ProductService.updateState error", e);
		} finally {
			clearProductCache(productId);
		}
		return false;
	}

	private void clearProductCache(long productId) {
		productLoader.clearCache(productId);
		productDetailLoader.clearCache(productId);
	}

	public void getSpec(String catId, Long productId, Model model){
		//获取分类下的规格种类,从ProductCategorySpec表中查询
		List<ProductCategorySpec> categorySpecs = productCategorySpecService.findByProductCategoryId(catId);
		List<Long> categoryIds = Lists.newArrayListWithExpectedSize(categorySpecs.size() + 1);
		categoryIds.add(0L);
		for (ProductCategorySpec categorySpec : categorySpecs) {
			categoryIds.add(categorySpec.getId());
		}
		//根据规格种类id查询规格详情
		Map<String, Object> param = Maps.newHashMapWithExpectedSize(1);
		param.put("specId in", categoryIds);
		List<ProductCategorySpecDetail> specDetails = productCategorySpecDetailService.list(param);
		//获取产品选取的规格和规格详情
		//先获取规格 从ProductSpec中获取
		List<Long> productSpecIds = productSpecService.getSpecIdByProduct(productId);
		//产品规格的组装
		List<EasyUiTreeDO> specs = Lists.newArrayListWithExpectedSize(categorySpecs.size());//产品规格的集合
		for (ProductCategorySpec categorySpec : categorySpecs) {
			EasyUiTreeDO treeDO = new EasyUiTreeDO();
			treeDO.setId(categorySpec.getId());
			treeDO.setText(categorySpec.getName());
			List<EasyUiTreeDO> child = Lists.newArrayList();
			for (ProductCategorySpecDetail categorySpecDetail : specDetails) {
				if(Long.valueOf(categorySpecDetail.getSpecId()).equals(Long.valueOf(categorySpec.getId()))){
					EasyUiTreeDO childDO = new EasyUiTreeDO();
					childDO.setId(categorySpecDetail.getId());
					childDO.setText(categorySpecDetail.getName());
					if(productSpecIds != null && productSpecIds.contains(Long.valueOf(categorySpecDetail.getId()))){
						childDO.setChecked(true);
					}
					child.add(childDO);
				}
			}
			treeDO.setChildren(child);
			specs.add(treeDO);
		}
		//获取规格详情
		List<ProductSpecDetail> productSpecDetails = productSpecDetailService.getByProduct(productId);
		for (ProductSpecDetail productSpecDetail : productSpecDetails) {
			List<String> list = Lists.newArrayList();
			String specDetailIdString = StringUtils.EMPTY;
			for (Long long1: productSpecDetail.getCategorySpecDetailIds()) {
				specDetailIdString += long1 + "-";
				for (ProductCategorySpecDetail productCategorySpecDetail : specDetails) {
					if(long1.equals(Long.valueOf(productCategorySpecDetail.getId()))){
						list.add(productCategorySpecDetail.getName());
						break;
					}
				}
			}
			productSpecDetail.setCategorySpecDetailNames(list);
			productSpecDetail.setSpecDetailIdString(specDetailIdString);
		}
		model.addAttribute("specs", specs);
		model.addAttribute("specDetails", productSpecDetails);
	}
}
